import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:get/get.dart';
import 'package:ichinesereader/exam/dto/assessment_question_record.body.dart';
import 'package:ichinesereader/models/common/StatusMessageResult.dart';
import 'package:ichinesereader/models/knowledgeword/bookWordsResult.dart';
import 'package:ichinesereader/models/knowledgeword/knowledgeDetailsResult.dart';
import 'package:ichinesereader/models/knowledgeword/knowledgeFolderTreeResult.dart';
import 'package:ichinesereader/models/knowledgeword/knowledgeWord.dart';
import 'package:ichinesereader/models/knowledgeword/knowledgeWordsByFolderResult.dart';
import 'package:ichinesereader/models/knowledgeword/folderKnowledgeWordsDto.dart';
import 'package:ichinesereader/models/knowledgeword/knowledgeWordsSearchResult.dart';
import 'package:ichinesereader/models/knowledgeword/knowledgeWordsTrashResult.dart';
import 'package:ichinesereader/models/knowledgeword/shareKnowledgeWordsDto.dart';
import 'package:ichinesereader/service/knowledgeword.dart';
import 'package:file_picker/file_picker.dart';
import 'package:ichinesereader/constants.dart';
import 'package:ichinesereader/utils/helper.dart';
import 'dart:convert';
import '../models/knowledgeword/WordCardQuestionsResult.dart';
import 'package:ichinesereader/exam/dto/assessment.response.dart';

class KnowledgeWordsController extends GetxController with StateMixin<dynamic> {
  KnowledgeWordsServiceProvider _knowledgeWordsServiceProvider =
      new KnowledgeWordsServiceProvider();

  Rx<StatusMessageResult> _statusMessageResult =
      Rx<StatusMessageResult>(StatusMessageResult());

  Rx<StatusMessageResult> get statusMessageResult => this._statusMessageResult;

  List<KnowledgeWord> _knowledgeWords = <KnowledgeWord>[].obs;

  List<KnowledgeWord> get knowledgeWords => this._knowledgeWords;

  List<KnowledgeWord> _recycleWords = <KnowledgeWord>[].obs;

  List<KnowledgeWord> get recycleWords => this._recycleWords;

  List<KnowledgeWord> _folders = <KnowledgeWord>[].obs;

  List<KnowledgeWord> get folders => this._folders;

  Rx<KnowledgeDetailsResult> _knowledgeDetailsResult =
      Rx<KnowledgeDetailsResult>(KnowledgeDetailsResult());

  Rx<KnowledgeDetailsResult> get knowledgeDetailsResult =>
      this._knowledgeDetailsResult;

  Rx<KnowledgeWordsSearchResult> _knowledgewordsSearchResult =
      Rx<KnowledgeWordsSearchResult>(KnowledgeWordsSearchResult());

  Rx<KnowledgeWordsSearchResult> get knowledgewordsSearchResult =>
      this._knowledgewordsSearchResult;

  Rx<KnowledgeWordsTrashResult> _knowledgewordsTrashResult =
      Rx<KnowledgeWordsTrashResult>(KnowledgeWordsTrashResult());

  Rx<KnowledgeWordsTrashResult> get knowledgewordsTrashResult =>
      this._knowledgewordsTrashResult;

  List<KnowledgeWord> mainFoldersAsWords = [];

  // Rx<String> _wordImageAddress = Rx<String>('');
  // Rx<String> get wordImageAddress => this._wordImageAddress;
  List<String?> _currDirName = <String?>[].obs;

  List<String?> get currDirName => this._currDirName;
  List<String?> _currdir = <String?>[].obs;

  List<String?> get currdir => this._currdir;
  List<String?> _folderdir = <String?>[].obs;

  List<String?> get folderdir => this._folderdir;
  List<String?> _folderDirName = <String?>[].obs;

  List<String?> get folderDirName => this._folderDirName;
  Rx<WordFolder> _wordFolder = Rx<WordFolder>(WordFolder());

  Rx<WordFolder> get wordFolder => this._wordFolder;
  String audioAddress = '';
  Rx<bool> mainMode = true.obs;
  String? recycleFolderId = '';
  Rx<bool> ifPinyin = true.obs;
  Rx<bool> ifWord = true.obs;
  Rx<bool> ifDefinition = true.obs;

  List<String>? handWriting;

  // List<QuestionResult>? choice;
  // List<QuestionResult>? vanish;
  List<QuestionItem>? questions;
  List<Map> records = [];
  int currWordQuizPage = 0;
  String? bookCode;

  @override
  void onInit() {
    super.onInit();
  }

  @override
  dispose() {
    super.dispose();
  }

  void searchKnowledgeWords(String query) async {
    try {
      change(_knowledgewordsSearchResult, status: RxStatus.loading());
      var response =
          await _knowledgeWordsServiceProvider.searchKnowledgeWords(query);
      if (response.statusCode == 200) {
        var data = knowledgeWordsSearchResultFromJson(response.bodyString);
        if (data.result != null) {
          _knowledgewordsSearchResult.value = data;
          change(_knowledgewordsSearchResult, status: RxStatus.success());
        }
      } else {
        change(null, status: RxStatus.empty());
      }
    } catch (error) {
      change(null, status: RxStatus.error('Oops, something wrong ...'.tr));
      print(error);
    }
  }

  void fetchKnowledgeWordsTrash() async {
    try {
      change(_knowledgewordsTrashResult, status: RxStatus.loading());
      var response =
          await _knowledgeWordsServiceProvider.getKnowledgeWordTrash();
      if (response.statusCode == 200) {
        var data = knowledgeWordsTrashResultFromJson(response.bodyString);
        if (data.result != null) {
          this._recycleWords.clear();

          data.result?.folders?.forEach((folder) {
            KnowledgeWord word = KnowledgeWord();
            word.folders = folder.folders;
            word.folderId = folder.id;
            word.text = folder.name;
            word.checked = false;
            this._recycleWords.add(word);
          });
          recycleFolderId = data.result?.id;
          if (recycleFolderId != null)
            this.fetchKnowledgeWordsByFolder(recycleFolderId.toString(), '');
          //
          // change(_knowledgewordsTrashResult, status: RxStatus.success());
        }
      } else {
        change(null, status: RxStatus.empty());
      }
    } catch (error) {
      change(null, status: RxStatus.error('Oops, something wrong ...'.tr));
      print(error);
    }
  }

  void changeDir(int index) {
    this._currdir.removeRange(index + 1, this._currdir.length);
    this._currDirName.removeRange(index + 1, this._currDirName.length);
    this.createFolderKnowledgeWord();
  }

  void changeFolderDir(int index) {
    this._folderdir.removeRange(index + 1, this._folderdir.length);
    this._folderDirName.removeRange(index + 1, this._folderDirName.length);
    this.getFolders();
  }

  //create folder word card by current dir
  void createFolderKnowledgeWord() {
    List<WordFolder>? folders = this._wordFolder.value.folders;
    String? folderId = this._wordFolder.value.id;
    String? teacherId = this._wordFolder.value.teacherId;
    bool ifshared = false;

    for (int i = 1; i < this._currdir.length; i++) {
      if (folders != null) {
        for (WordFolder folder in folders) {
          if (folder.id == _currdir[i]) {
            folderId = folder.id.toString();
            folders = folder.folders;
            ifshared = false;
            break;
          } else if (folder.teacherId == _currdir[i]) {
            teacherId = folder.teacherId.toString();
            folders = folder.folders;
            ifshared = true;
            break;
          }
        }
      }
    }

    mainFoldersAsWords = [];
    folders?.forEach((folder) {
      KnowledgeWord word = KnowledgeWord();
      word.folders = folder.folders;
      word.folderId = folder.id;
      word.teacherId = folder.teacherId;
      word.text = folder.name;
      word.checked = false;
      mainFoldersAsWords.add(word);
    });

    if (!ifshared)
      fetchKnowledgeWordsByFolder(folderId!, '');
    else
      fetchKnowledgeWordsByTeacher(teacherId!, '');
    // this._knowledgeWords.assignAll(mainFoldersAsWords);
  }

  //create folder word card by current dir
  void getFolders() {
    List<WordFolder>? folders = this._wordFolder.value.folders;
    // ignore: unused_local_variable
    String folderId = this._wordFolder.value.id.toString();
    for (int i = 1; i < this._folderdir.length; i++) {
      if (folders != null) {
        for (WordFolder folder in folders) {
          if (folder.id == _folderdir[i]) {
            folderId = folder.id.toString();
            folders = folder.folders;
            break;
          }
        }
      }
    }
    //print(folderId);
    mainFoldersAsWords = [];
    folders?.forEach((folder) {
      KnowledgeWord word = KnowledgeWord();
      word.folders = folder.folders;
      word.folderId = folder.id;
      word.text = folder.name;
      word.checked = false;
      mainFoldersAsWords.add(word);
    });
    this._folders.clear();
    this._folders.addAll(mainFoldersAsWords);
    change(_folders, status: RxStatus.success());
  }

  void updateSetting() {
    change(ifWord, status: RxStatus.success());
    change(ifPinyin, status: RxStatus.success());
    change(ifDefinition, status: RxStatus.success());
  }

  void fetchKnowledgeFolderOnlyTree() async {
    try {
      var response =
          await _knowledgeWordsServiceProvider.getKnowledgeWordFolderTree();
      if (response.statusCode == 200) {
        var data = knowledgeFolderTreeResultFromJson(response.bodyString);
        if (data.result != null) {
          mainFoldersAsWords = [];
          // this._mainFolderId = data.result!.id.toString();
          data.result?.folders?.forEach((folder) {
            KnowledgeWord word = KnowledgeWord();
            word.folders = folder.folders;
            word.folderId = folder.id;
            word.text = folder.name;
            word.checked = false;
            mainFoldersAsWords.add(word);
          });

          this._wordFolder.value = data.result!;
          if (_currdir.length == 0) {
            this._currdir.add(data.result?.id);
            this._currDirName.add(data.result?.name);
          }

          if (_folderdir.length == 0) {
            this._folderdir.add(data.result?.id);
            this._folderDirName.add(data.result?.name);
            getFolders();
          }
        }
      } else {
        //change(null, status: RxStatus.empty());
      }
    } catch (error) {
      //change(null, status: RxStatus.error('Oops, something wrong ...'.tr));
      print(error);
    }
  }

  void fetchKnowledgeFolderTree(bool oper) async {
    if ((this._currdir.length != 0) && (!oper)) {
      createFolderKnowledgeWord();
      return;
    }
    try {
      var response =
          await _knowledgeWordsServiceProvider.getKnowledgeWordFolderTree();
      if (response.statusCode == 200) {
        var data = knowledgeFolderTreeResultFromJson(response.bodyString);
        if (data.result != null) {
          mainFoldersAsWords = [];
          // this._mainFolderId = data.result!.id.toString();
          data.result?.folders?.forEach((folder) {
            KnowledgeWord word = KnowledgeWord();
            word.folders = folder.folders;
            word.folderId = folder.id;
            word.text = folder.name;
            word.checked = false;
            mainFoldersAsWords.add(word);
          });

          this._wordFolder.value = data.result!;
          if (_currdir.length == 0) {
            this._currdir.add(data.result?.id);
            this._currDirName.add(data.result?.name);
          }

          if (_folderdir.length == 0) {
            this._folderdir.add(data.result?.id);
            this._folderDirName.add(data.result?.name);
            getFolders();
          }

          createFolderKnowledgeWord();
          // this._knowledgeWords.assignAll(mainFoldersAsWords);
          // change(_knowledgeFolderTreeResult, status: RxStatus.success());
        }
      } else {
        //change(null, status: RxStatus.empty());
      }
    } catch (error) {
      //change(null, status: RxStatus.error('Oops, something wrong ...'.tr));
      print(error);
    }
  }

  void changeAllWordCardStatus() {
    knowledgeWords.forEach((word) {
      if (word.checked != null) word.checked = !word.checked!;
    });
    change(knowledgeWords, status: RxStatus.success());
  }

  Future<WordCardQuestionsResult> fetchWordQuiz(
      String? bookCode, List<String>? wordIds) async {
    var data = WordCardQuestionsResult();
    EasyLoading.show();
    try {
      var response = await _knowledgeWordsServiceProvider
          .getKnowledgeWordQuestions(bookCode, wordIds);
      if (response.statusCode == 200) {
        // print(response.bodyString);
        data = wordCardQuestionsResultFromJson(response.bodyString);
        if (data.result != null) {
          this.handWriting = data.result?.handWriting;
          // this.choice = data.result?.choice;
          // this.vanish = data.result?.vanish;
          questions = [];
          records = [];
          if (data.result?.match != null) {
            questions!.addAll(data.result!.match![0].question!);

            QuestionSingleStep record = QuestionSingleStep(
                questionId: data.result!.match![0].id, number: 1, answer: []);
            records.add(record.toJson());
          }
          if (data.result?.choice != null) {
            questions!.addAll(data.result!.choice![0].question!);
            QuestionSingleStep record = QuestionSingleStep(
                questionId: data.result!.choice![0].id, number: 1, answer: []);
            records.add(record.toJson());
          }
          if (data.result?.vanish != null) {
            questions!.addAll(data.result!.vanish![0].question!);
            QuestionSingleStep record = QuestionSingleStep(
                questionId: data.result!.vanish![0].id, number: 1, answer: []);
            records.add(record.toJson());
          }
          if (data.result?.option != null) {
            questions!.addAll(data.result!.option![0].question!);
            QuestionSingleStep record = QuestionSingleStep(
                questionId: data.result!.option![0].id, number: 1, answer: []);
            records.add(record.toJson());
          }
          //Get.to(() => WordCardQuiz());
        }
      }
    } catch (error) {
      change(null, status: RxStatus.error('Oops, something wrong ...'.tr));
      print(error);
    } finally {
      EasyLoading.dismiss();
    }
    return data;
  }

  void fetchKnowledgeWordsByFolder(String folderId, String level) async {
    try {
      change(_knowledgeWords, status: RxStatus.loading());
      if (folderId != '') {
        if (this.mainMode.value)
          this._knowledgeWords.assignAll(mainFoldersAsWords);
        // this._folders.clear();
        // this._folders.addAll(mainFoldersAsWords);
        var response = await _knowledgeWordsServiceProvider
            .getKnowledgeWordsByFolder(folderId, level);
        if (response.statusCode == 200) {
          var data = knowledgeWordsByFolderResultFromJson(response.bodyString);
          if (data.result != null && data.result?.list != null) {
            if (this.mainMode.value) {
              this
                  ._knowledgeWords
                  .addAll(data.result?.list as List<KnowledgeWord>);
            } else {
              this
                  ._recycleWords
                  .addAll(data.result?.list as List<KnowledgeWord>);
            }
          }
        }
        if (this.mainMode.value) {
          change(_knowledgeWords, status: RxStatus.success());
          change(_folders, status: RxStatus.success());
        } else {
          change(_recycleWords, status: RxStatus.success());
        }
      } else {
        change(null, status: RxStatus.empty());
      }
    } catch (error) {
      change(null, status: RxStatus.error('Oops, something wrong ...'.tr));
      print(error);
    }
  }

  void fetchKnowledgeWordsByTeacher(String teacherId, String level) async {
    try {
      change(_knowledgeWords, status: RxStatus.loading());
      if (teacherId != '') {
        if (this.mainMode.value)
          this._knowledgeWords.assignAll(mainFoldersAsWords);
        var response = await _knowledgeWordsServiceProvider
            .getKnowledgeWordsByTeacher(teacherId, level);
        if (response.statusCode == 200) {
          var data = knowledgeWordsByFolderResultFromJson(response.bodyString);
          if (data.result != null && data.result?.list != null) {
            if (this.mainMode.value) {
              this
                  ._knowledgeWords
                  .addAll(data.result?.list as List<KnowledgeWord>);
            } else {
              this
                  ._recycleWords
                  .addAll(data.result?.list as List<KnowledgeWord>);
            }
          }
        }
        if (this.mainMode.value) {
          change(_knowledgeWords, status: RxStatus.success());
          change(_folders, status: RxStatus.success());
        } else {
          change(_recycleWords, status: RxStatus.success());
        }
      } else {
        change(null, status: RxStatus.empty());
      }
    } catch (error) {
      change(null, status: RxStatus.error('Oops, something wrong ...'.tr));
      print(error);
    }
  }

//{"status":1000,"message":"create knowledge word success","result":{"id":"7c351cbc-b133-4787-85ad-1afadbf51411"}}
  void createKnowledgeWord(KnowledgeWord word, String folderId) async {
    try {
      var response = await _knowledgeWordsServiceProvider.createKnowledgeWord(
          word, folderId);
      if (response.statusCode == 200) {
        StatusMessageResult data =
            statusMessageResultFromJson(response.bodyString);
        _statusMessageResult.value = data;
        showSnackMsg(_statusMessageResult.value.message!);
        // Get.snackbar('Message'.tr, _statusMessageResult.value.message!.tr,
        //     backgroundColor: Get.theme.primaryColorDark,
        //     colorText: Get.theme.primaryColorLight,
        //     snackPosition: SnackPosition.BOTTOM);
        fetchKnowledgeFolderTree(false);
      } else {}
    } catch (error) {
      print(error);
    }
  }

  void updateKnowledgeWord(KnowledgeWord word) async {
    try {
      var response =
          await _knowledgeWordsServiceProvider.updateKnowledgeWord(word);
      if (response.statusCode == 200) {
        StatusMessageResult data =
            statusMessageResultFromJson(response.bodyString);
        _statusMessageResult.value = data;
        showSnackMsg(_statusMessageResult.value.message!);
        // Get.snackbar('Message'.tr, _statusMessageResult.value.message!.tr,
        //     backgroundColor: Get.theme.primaryColorDark,
        //     colorText: Get.theme.primaryColorLight,
        //     snackPosition: SnackPosition.BOTTOM);
        fetchKnowledgeFolderTree(false);
      } else {}
    } catch (error) {
      print(error);
    }
  }

  void createKnowledgeWordFolder(String parentFolderId, String folderId) async {
    try {
      var response = await _knowledgeWordsServiceProvider
          .createKnowledgeWordFolder(parentFolderId, folderId);
      if (response.statusCode == 200) {
        StatusMessageResult data =
            statusMessageResultFromJson(response.bodyString);
        _statusMessageResult.value = data;
        fetchKnowledgeFolderTree(true);
      } else {}
    } catch (error) {
      print(error);
    }
  }

  Future<String> uploadWordFile(PlatformFile pfile) async {
    try {
      var response =
          await _knowledgeWordsServiceProvider.uploadKnowledgeFile(pfile);

      final body = await response.stream.transform(utf8.decoder).join();
      print(body);
      if (response.statusCode == 200) {
        StatusMessageResult data = statusMessageResultFromJson(body);
        String fileId = data.result["fileId"];
        // https://resources.ichinesereader.com/media/knowledgelib/cust/047cbb5c-117a-4a34-926f-2777fb86d0c0.jpeg
        // this._wordImageAddress.value =
        return '${Constants.BaseResources}media/knowledgelib/cust/' + fileId;
      } else {
        return '';
      }
    } catch (error) {
      print(error);
      return '';
    }
  }

  Future<String> generateAudioByWord(String word) async {
    try {
      var response =
          await _knowledgeWordsServiceProvider.generateAudioByWord(word);
      if (response.statusCode == 200) {
        StatusMessageResult data =
            statusMessageResultFromJson(response.bodyString);
        //print(data.result["result"]);
        this.audioAddress = data.result["result"];
      } else {}
    } catch (error) {
      print(error);
    }
    return this.audioAddress;
  }

  void shareKnowledgeWordsToStudents(ShareKnowledgeWordsDto dto) async {
    try {
      var response =
          await _knowledgeWordsServiceProvider.shareKnowledgeWords(dto);
      if (response.statusCode == 200) {
        StatusMessageResult data =
            statusMessageResultFromJson(response.bodyString);
        _statusMessageResult.value = data;
      } else {}
    } catch (error) {
      print(error);
    }
  }

  void moveKnowledgeWords(FolderKnowledgeWordsDto dto, String fromFolderId,
      String toFolderId, bool keepFlag) async {
    try {
      var response = await _knowledgeWordsServiceProvider.moveKnowledgeWords(
          dto, fromFolderId, toFolderId, keepFlag);
      if (response.statusCode == 200) {
        StatusMessageResult data =
            statusMessageResultFromJson(response.bodyString);
        _statusMessageResult.value = data;
        if (this.mainMode.value)
          fetchKnowledgeFolderTree(true);
        else
          this.fetchKnowledgeWordsTrash();
      }
    } catch (error) {
      print(error);
    }
  }

  void saveKnowledgeWords(FolderKnowledgeWordsDto dto, String folderId) async {
    try {
      var response = await _knowledgeWordsServiceProvider.saveKnowledgeWords(
          dto.knowledgeIds, folderId);
      if (response.statusCode == 200) {
        StatusMessageResult data =
            statusMessageResultFromJson(response.bodyString);
        _statusMessageResult.value = data;
        // release the select after moved
        _knowledgeWords.forEach((word) {
          word.checked = false;
        });
        showSnackMsg('Move success'.tr);
        change(this._knowledgeWords, status: RxStatus.success());
      }
    } catch (error) {
      print(error);
    }
  }

  FolderKnowledgeWordsDto getSelectedFolderAWord() {
    FolderKnowledgeWordsDto dto = FolderKnowledgeWordsDto();
    dto.knowledgeIds = [];
    dto.folderIds = [];
    _knowledgeWords.forEach((word) {
      if (word.checked != null && word.checked!) {
        if (word.folderId == '' || word.folderId == null) {
          dto.knowledgeIds?.add(word.id.toString());
        } else {
          dto.folderIds?.add(word.folderId.toString());
        }
      }
    });
    return dto;
  }

  FolderKnowledgeWordsDto getSelectedRecycledFolderAWord() {
    FolderKnowledgeWordsDto dto = FolderKnowledgeWordsDto();
    dto.knowledgeIds = [];
    dto.folderIds = [];
    _recycleWords.forEach((word) {
      if (word.checked != null && word.checked!) {
        if (word.folderId == '' || word.folderId == null) {
          dto.knowledgeIds?.add(word.id.toString());
        } else {
          dto.folderIds?.add(word.folderId.toString());
        }
      }
    });
    return dto;
  }

  void removeKnowledgeWordsFromFolder(
      FolderKnowledgeWordsDto dto, String folderId) async {
    try {
      var response = await _knowledgeWordsServiceProvider
          .removeKnowledgeWordsFromFolder(dto, folderId);
      //print(response.statusCode);
      if (response.statusCode == 200) {
        // StatusMessageResult data =
        //     statusMessageResultFromJson(response.bodyString);
        // _statusMessageResult.value = data;
        fetchKnowledgeFolderTree(true);
      } else {}
    } catch (error) {
      print(error);
    }
  }

  void fetchBasicKnowledgeWords() async {
    try {
      var response =
          await _knowledgeWordsServiceProvider.getBasicKnowledgeWords();
      if (response.statusCode == 200) {
        var data = bookWordsResultFromJson(response.bodyString);
        if (data.result?.list != null) {
          List<KnowledgeWord> items = data.result?.list as List<KnowledgeWord>;
          items.sort((a, b) {
            int end1 = a.level != null ? a.level!.toInt() : 0;
            var end2 = b.level != null ? b.level!.toInt() : 0;
            return end1.compareTo(end2);
          });
          _knowledgeWords.assignAll(items);
          if (_knowledgeWords.length > 0)
            change(_knowledgeWords, status: RxStatus.success());
          else
            change(null, status: RxStatus.empty());
        }
      } else {
        change(null, status: RxStatus.empty());
      }
    } catch (error) {
      change(null, status: RxStatus.error('Oops, something wrong ...'.tr));
      print(error);
    }
  }

  void fetchKnowledgeWordsByBookcode(
      String bookcode, bool simplified, bool mandarin) async {
    try {
      var response = await _knowledgeWordsServiceProvider
          .getKnowledgeWordsByBookCode(bookcode, simplified, mandarin);
      if (response.statusCode == 200) {
        var data = bookWordsResultFromJson(response.bodyString);
        if (data.result?.list != null) {
          List<KnowledgeWord> items = data.result?.list as List<KnowledgeWord>;
          items.sort((a, b) {
            int end1 = a.level != null ? a.level!.toInt() : 0;
            var end2 = b.level != null ? b.level!.toInt() : 0;
            return end1.compareTo(end2);
          });
          _knowledgeWords.assignAll(items);
          if (_knowledgeWords.length > 0)
            change(_knowledgeWords, status: RxStatus.success());
          else
            change(null, status: RxStatus.empty());
        }
      } else {
        change(null, status: RxStatus.empty());
      }
    } catch (error) {
      change(null, status: RxStatus.error('Oops, something wrong ...'.tr));
      print(error);
    }
  }

  void fetchKnowledgeDetailsByBookcode(
      String bookcode, bool simplified, bool mandarin) async {
    try {
      change(_knowledgeDetailsResult, status: RxStatus.loading());
      var response = await _knowledgeWordsServiceProvider
          .getKnowledgeDetailsByBookCode(bookcode, simplified, mandarin);
      if (response.statusCode == 200) {
        var data = knowledgeItemsResultFromJson(response.bodyString);
        if (data.result != null) {
          _knowledgeDetailsResult.value = data;
          change(_knowledgeDetailsResult, status: RxStatus.success());
        }
      } else {
        change(null, status: RxStatus.empty());
      }
    } catch (error) {
      change(null, status: RxStatus.error('Oops, something wrong ...'.tr));
      print(error);
    }
  }

  Future<KnowledgeDetailsResult> getKnowledgeDetailsByBookcode(
      String bookcode, bool simplified, bool mandarin) async {
    var data = KnowledgeDetailsResult();
    try {
      var response = await _knowledgeWordsServiceProvider
          .getKnowledgeDetailsByBookCode(bookcode, simplified, mandarin);
      if (response.statusCode == 200) {
        data = knowledgeItemsResultFromJson(response.bodyString);
      }
    } catch (error) {
      print(error);
    }
    return data;
  }
}
